> ## Documentation Index
> Fetch the complete documentation index at: https://edimez14-password_generator.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Saved Passwords

> Save, view, update, and manage passwords with metadata including URLs and page names

## Overview

The Saved Passwords feature allows authenticated users to securely store generated passwords along with metadata such as the associated URL and page name. Each user has their own isolated password vault with full CRUD (Create, Read, Update, Delete) capabilities.

## Data Model

The `SavedPasswords` model stores password entries with associated metadata (`models.py:5-14`):

```python theme={null}
class SavedPasswords(models.Model):
    name_pages = models.CharField(max_length=200, blank=True)
    url = models.URLField(max_length=200)
    password_saved = models.CharField(max_length=200)
    user = models.ForeignKey(
        Users, on_delete=models.CASCADE, related_name="saved_passwords"
    )
    
    def __str__(self):
        return f"{self.id} - {self.name_pages} (User: {self.user.username})"
```

> **Page Name**
>
> Optional descriptive label for the password entry (e.g., "GitHub", "Email Account")

> **URL**
>
> Required URL field to identify where the password is used

> **Password**
>
> The actual password string to be saved

> [!NOTE]
>
> Each password entry is linked to a specific user via a foreign key relationship. The `on_delete=models.CASCADE` ensures that when a user is deleted, all their saved passwords are automatically removed.

## Saving Passwords

Authenticated users can save passwords with metadata through the API.

### API Endpoint

**URL**: `POST /api/passwords/save/`

**Authentication**: Required (IsAuthenticated)

**Request Body**:

```json theme={null}
{
  "name_pages": "GitHub Account",
  "url": "https://github.com",
  "password_saved": "!42a#Bc7de€",
  "user": 1
}
```

**Response**:

```json theme={null}
"password saved successfully"
```

### Implementation

The save endpoint is implemented in `views.py:30-59`:

```python theme={null}
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def save_passwords(request):
    try:
        serializer = SavedPasswordsSerializer(data=request.data)
        
        if serializer.is_valid():
            serializer.save()
            
            passwords = SavedPasswords.objects.filter(
                user=serializer.data['user'])
            passwords.password_saved = serializer.data['password_saved']
            passwords.url = serializer.data['url']
            passwords.name_pages = serializer.data['name_pages']
            for password in passwords:
                password.save()
            
            return Response("password saved successfully", status=status.HTTP_200_OK)
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    except KeyError:
        return Response({'error': 'Missing required fields.'}, status=status.HTTP_400_BAD_REQUEST)
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
```

### Frontend Form

The React form component for saving passwords (`FormSavedPasswords.jsx`):

```jsx theme={null}
export default function FormSavedPasswords({ password, onDataChange }) {
    const [formData, setFormData] = useState({
        namePages: '',
        url: '',
        user: JSON.parse(sessionStorage.getItem('user'))?.id || null
    });
    const [passwordSaved, setPasswordSaved] = useState(password);
    
    const handleChange = (e) => {
        const updatedFormData = { ...formData, [e.target.name]: e.target.value };
        setFormData(updatedFormData);
        onDataChange({ ...updatedFormData, passwordSaved: passwordSaved });
    };
    
    return (
        <form>
            <Input
                name="namePages"
                label="Page name"
                placeholder="Enter the page name"
                onChange={handleChange}
            />
            <Input
                name="url"
                label="URL"
                placeholder="Enter the URL"
                type="url"
                onChange={handleChange}
            />
            <Input
                name="passwordSaved"
                label="Password to save"
                value={passwordSaved}
                type="text"
            />
        </form>
    );
}
```

> [!TIP]
>
> The form pre-fills the password field with a newly generated password, but users can modify it before saving.

## Viewing Saved Passwords

Users can retrieve all their saved passwords through a dedicated endpoint.

### API Endpoint

**URL**: `GET /api/passwords/saved/`

**Authentication**: Required (IsAuthenticated)

**Response**:

```json theme={null}
{
  "message": "Passwords saved by the user johndoe: ",
  "passwords": [
    {
      "id": 1,
      "name_pages": "GitHub Account",
      "url": "https://github.com",
      "password_saved": "!42a#Bc7de€",
      "user": 1
    },
    {
      "id": 2,
      "name_pages": "Email",
      "url": "https://gmail.com",
      "password_saved": "#78x@Yz2fg!",
      "user": 1
    }
  ]
}
```

### Implementation

The view endpoint (`views.py:62-85`):

```python theme={null}
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def view_all_saved_passwords(request):
    try:
        user = request.user
        
        passwords = SavedPasswords.objects.filter(user=user)
        
        serializer = SavedPasswordsSerializer(passwords, many=True)
        
        return Response(
            {
                "message": f"Passwords saved by the user {user.username}: ",
                "passwords": serializer.data
            },
            status=status.HTTP_200_OK
        )
    
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
```

> [!NOTE]
>
> The endpoint automatically filters passwords by the authenticated user, ensuring users can only access their own password entries.

## Updating Saved Passwords

Users can modify existing password entries using the update endpoint.

### API Endpoint

**URL**: `PUT /api/passwords/update/<pk>/`

**Authentication**: Required (IsAuthenticated)

**Request Body** (partial updates supported):

```json theme={null}
{
  "name_pages": "GitHub Personal Account",
  "url": "https://github.com/johndoe"
}
```

**Response**:

```json theme={null}
"data saved"
```

### Implementation

The update endpoint (`views.py:88-103`):

```python theme={null}
@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def update_saved_password(request, pk):
    try:
        password_instance = SavedPasswords.objects.get(
            pk=pk, user=request.user)
        serializer = SavedPasswordsSerializer(
            password_instance, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response("data saved", status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    except SavedPasswords.DoesNotExist:
        return Response({'error': 'Password not found.'}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
```

> [!WARNING]
>
> The endpoint verifies that the password entry belongs to the authenticated user (`pk=pk, user=request.user`), preventing unauthorized modifications.

## Deleting Saved Passwords

Users can permanently delete password entries they no longer need.

### API Endpoint

**URL**: `DELETE /api/passwords/delete/<pk>/`

**Authentication**: Required (IsAuthenticated)

**Response**:

```json theme={null}
{
  "message": "Password deleted successfully"
}
```

### Implementation

The delete endpoint (`views.py:106-117`):

```python theme={null}
@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def delete_saved_password(request, pk):
    try:
        password_instance = SavedPasswords.objects.get(
            pk=pk, user=request.user)
        password_instance.delete()
        return Response({"message": "Password deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
    except SavedPasswords.DoesNotExist:
        return Response({'error': 'Password not found.'}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
```

## CRUD Operations Summary

> **Create**
>
> `POST /api/passwords/save/` - Save new password with metadata

> **Read**
>
> `GET /api/passwords/saved/` - Retrieve all saved passwords

> **Update**
>
> `PUT /api/passwords/update/<pk>/` - Modify existing password entry

> **Delete**
>
> `DELETE /api/passwords/delete/<pk>/` - Remove password entry

## UI Features

The frontend provides several components for managing saved passwords:

### Password Display Component

The `ViewPasswords.jsx` component displays saved passwords in a user-friendly format with search and filter capabilities.

### Search Functionality

The `SearchBar.jsx` component allows users to quickly find saved passwords by name or URL.

### Modal Interface

The `ModalSavedPasswords.jsx` component provides a modal dialog for viewing and editing password details.

## Data Serialization

The `SavedPasswordsSerializer` handles all data validation and serialization (`serializers.py:5-8`):

```python theme={null}
class SavedPasswordsSerializer(serializers.ModelSerializer):
    class Meta:
        model = SavedPasswords
        fields = "__all__"
```

## Security Considerations

> [!WARNING]
>
> **Important Security Notes**:
>
> * Passwords are stored in plain text in the database. For production use, implement encryption at rest.
> * Always use HTTPS to prevent password interception during transmission.
> * Implement proper access controls to ensure users can only access their own passwords.
> * Consider implementing password encryption using libraries like `django-encrypted-model-fields`.

### User Isolation

The system enforces strict user isolation:

```python theme={null}
# All queries filter by authenticated user
passwords = SavedPasswords.objects.filter(user=request.user)

# Updates and deletes verify ownership
password_instance = SavedPasswords.objects.get(pk=pk, user=request.user)
```

## Error Handling

All endpoints include comprehensive error handling:

| Error Type | HTTP Status | Response |
| - | - | - |
| Missing fields | 400 | `{"error": "Missing required fields."}` |
| Not found | 404 | `{"error": "Password not found."}` |
| Validation error | 400 | `{...serializer.errors}` |
| Server error | 500 | `{"error": "<error message>"}` |

> [!TIP]
>
> For best practices, implement client-side validation before submitting password data to reduce unnecessary API calls and improve user experience.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.